<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>GDatabase Documentation</title>
<style type="text/css">
<!--
body {
	font: 100% Verdana, Arial, Helvetica, sans-serif;
	background: #666666;
	margin: 0; /* it's good practice to zero the margin and padding of the body element to account for differing browser defaults */
	padding: 0;
	text-align: center; /* this centers the container in IE 5* browsers. The text is then set to the left aligned default in the #container selector */
	color: #000000;
	width: 80%;
}
.oneColLiqCtrHdr #container {
	width: 80%;  /* this will create a container 80% of the browser width */
	background: #FFFFFF;
	margin: 0 auto; /* the auto margins (in conjunction with a width) center the page */
	border: 1px solid #000000;
	text-align: left; /* this overrides the text-align: center on the body element. */
	font-size: small;
}
.oneColLiqCtrHdr #header {
	background: #DDDDDD; 
	padding: 0 10px 0 20px;  /* this padding matches the left alignment of the elements in the divs that appear beneath it. If an image is used in the #header instead of text, you may want to remove the padding. */
}
.oneColLiqCtrHdr #header h1 {
	margin: 0; /* zeroing the margin of the last element in the #header div will avoid margin collapse - an unexplainable space between divs. If the div has a border around it, this is not necessary as that also avoids the margin collapse */
	padding: 10px 0; /* using padding instead of margin will allow you to keep the element away from the edges of the div */
}
.oneColLiqCtrHdr #mainContent {
	padding: 0 20px; /* remember that padding is the space inside the div box and margin is the space outside the div box */
	background: #FFFFFF;
}
.oneColLiqCtrHdr #footer { 
	padding: 0 10px; /* this padding matches the left alignment of the elements in the divs that appear above it. */
	background:#DDDDDD;
} 
.oneColLiqCtrHdr #footer p {
	margin: 0; /* zeroing the margins of the first element in the footer will avoid the possibility of margin collapse - a space between divs */
	padding: 10px 0; /* padding on this element will create space, just as the the margin would have, without the margin collapse issue */
}
.style3 {font-size: small}
.lua {
	font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: x-small;
	background-color: #CCCCCC;
	border: 1px dashed #999999;
}
.style4 {font-size: medium}
-->
</style>
</head>

<body class="oneColLiqCtrHdr">

<div id="container">
  <div id="header">
    <h1>GDatabase Documentation</h1>
  <!-- end #header --></div>
  <div id="mainContent">
    <h3>GDATABASE Version 1.21<br />
      By Tomato3017</h3>
    <h4>Purpose</h4>
    <p class="style3"> This addon provides access to making database connections that are monitored and controlled by this addon. This allows the programmer to not worry about the connection and focus on the heart of his/her addon. This addon automatically checks the connection to make sure it is still accessable and runs a &quot;keep alive&quot; routine on it to make sure the MYSQL server doesn't kill the connection due to inactivity. If for some reason the connection goes down, this script will attempt at a regular interval to establish a connection. During this time all queries to the database in question will be returned as false.<br />
</p>
    <p class="style3">This addon also provides an easy way to handle threaded queries(all you gotta do is provide a callback function). This allows the programmer to not worry if the thread is done and to focus elsewhere. The threaded queries are handled like a FIFO stack. This means if you send a bunch of threaded queries at once, the script will automatically queue them all up and process them in a manageable fashion and prevent a connection overload.<br />
      The addon also allows you to visually reconnect or kill any connection via the console. It also will display the status of the connection.</p>
    <h4>Requirements</h4>
    <p class="style3">A brain<br />
      LUA skills<br />
      MYSQL server(duh!)<br />
    gm_mysql V1.8(Included), While 1.8 is what I support, this addon will work with gm_mysql v1.6 and above.<br />
    <strong>NOTE:</strong> Please read documentation and gcommunicate for examples.</p>
    <h4>Install</h4>
    <ul>
      <li>Copy GDatabase into the addon's folder.</li>
      <li>Run install modules.bat</li>
    </ul>
    <h4>Changelog</h4>
    <p class="style3">v1.0:initial release</p>
    <p class="style3">v1.1: </p>
    <ul>
      <li>Numerous bug fixes. </li>
      <li>Fixed having more then 1 concurrent thread making the MYSQL server disconnect(gm_mysql seems to not like multiple threads in 1 frame)</li>
      <li>Added my ptimer module. This module wraps around the basic timer module and allows you to group timers and mass stop and start them in this manner.</li>
      <li>Added <strong>gdatabase.AddTimer</strong> and <strong>gdatabase.RemoveTime</strong><strong>r</strong> see function list in documentation for uses.</li>
      <li>Added pcall's to the hook run function so any bad hooks won't mess up GDatabase.</li>
    </ul>
    <p>v1.2:</p>
    <ul>
      <li>Fixed bug where the threads for multiple connections weren't running</li>
      <li>Fixed an error where gdatabase.threadedquery returned nil instead of true.</li>
    </ul>
    <p>v1.21</p>
    <ul>
      <li>Changed the function gdatabase.threadedquery to gdatabase.ThreadedQuery(I added backwards compatability for the old one)</li>
      <li>Added example file to release</li>
      <li>Corrected version numbering(oops!)</li>
    </ul>
    <h4>Credits</h4>
    <p class="style3">Spacetech: Lots of help and testing.<br />
    ULIB TEAM: Gave me a bunch of ideas, also gave me permission to use their module loading code. Thanks!<br />
    Andy Vincent: Thanks for writing a threaded mysql dll for us to use!<br />
    Musex Team: I copied their batch file for module installation. I was too lazy to write my own :s</p>
    <h4>Console Commands</h4>
    <p class="style3"><strong>gdatabase_connections</strong>- Displays all the connections that GDatabase is handling and their status.</p>
    <p class="style3"><strong>gdatabase_killall</strong>- Kills all database's, note:ANY addon using GDatabase will have their connections to the database become invalid.</p>
    <p class="style3"><strong>gdatabase_kill #</strong>- Kills the connection with the specified index.</p>
    <p class="style3"><strong>gdatabase_reconnectall</strong>- Reconnects all the connections in Gdatabase. Useful if the server loses it's internet connection and needs to be reestablished to all open database's.</p>
    <h4>Module Loading</h4>
    <p class="style3">This addon supports module loading(just like ULIB). By doing it this way, you can make sure your addon loads AFTER GDatabase.</p>
    <h4>Config</h4>
    <p class="style3">Please look at config.lua for config variables.</p>
    <p class="style3">Couple of specfic notes:</p>
    <ul>
      <li><span class="style3"><strong> gdatabase.config.maxqueuesize</strong>: This is very useful, it will keep the queue size from becoming very large. So if for some reason or another a disconnect hook breaks or the keep alive refresh time is very long, this will prevent the queue from getting very large and making memory issues.</span></li>
      <li class="style3"><strong>gdatabase.config.concurrentthreads</strong>: Number of threads that will be processed from the queue at any one time. In making GDatabase and testing, I noticed that setting this above 1 would sometimes make the connection to the database break when a heavy load came. I traced it to the gm_mysql dll and posted it as a bug in that forum.</li>
      <li class="style3"> <strong>gdatabase.config.debug</strong>: Makes Gdatabase output whenever it does something, alot of messages will be posted but this is good during development. </li>
    </ul>
    <h4>Notes</h4>
    <p class="style3">I have commented all the required function fairly well. Please post in the GDatabase thread with any questions.</p>
    <p>&nbsp;</p>
    <hr />
    <h2>Reference Documenation</h2>
    <h4 class="style4">Public Functions</h4>
    <h5 class="style3">gdatabase.MakeConnection(databasehost, databaseuser, databasepassword, databasename, tblSettings)</h5>
    <ul>
      <li class="style3">Makes a connection to the SQL server specified, returns the index needed to access the database from now on. Returns false if the connection was not successful.
        <ul>
          <li> <em>databasehost</em>: String, Ip address of the MYSQL server</li>
          <li><em>databaseuser</em>: String, Username of the database in question.</li>
          <li><em>databasepassword</em>: String, Password that corresponds to the Username given.</li>
          <li><em>databasename</em>:String, Name of the database to connect to.</li>
          <li><em>tblSettings</em>: This is a table of custom settings that you can pass when making a connection. This will override what is in the config.lua with the settings you pass here. The settings are based on the key of the table.  You can also pass values that aren't even a database setting. For example, to change the keepaliverefresh and reconnectrate to a custom setting you would do the following<div class="lua">sometable = {}<br />
      sometable[&quot;reconnectrate&quot;] = 300<br />
      sometable[&quot;keepaliverefresh&quot;] = 400<br />
    gdatabase.MakeConnection(&quot;192.168.1.10&quot;, &quot;user&quot;, &quot;password&quot;, &quot;somedbname&quot;, sometable</div>
          </li>
        </ul>
      </li>
    </ul>
    <h5>&nbsp;</h5>
    <h5 class="style3">gdatabase.KillConnection(intDatabaseIndex)</h5>
    <ul>
      <li class="style3">Kills the specified connection. Returns true if successful, false if something went wrong. This also removes all threads that are currently running that are attached to the database.
        <ul>
          <li><em>intDatabaseIndex</em>: Integer, Index of the database to kill.</li>
        </ul>
      </li>
    </ul>
    <p>&nbsp;</p>
    <h5 class="style3">gdatabase.Query(strQuery, intDatabaseIndex)</h5>
    <ul>
      <li class="style3">Does a NON-threaded query to the database. Returns the data. Returns false if the database doesn't exist,timed out, or is a bad query.      
        <ul>
          <li><em>strQuery</em>: String, Query to be sent to the database</li>
          <li><em>intDatabaseIndex</em>: Integer, Index of the database.</li>
        </ul>
      </li>
    </ul>
    <p>&nbsp;</p>
    <h5 class="style3">gdatabase.CheckForConnection(intDatabaseIndex)</h5>
    <ul>
      <li class="style3">Returns true if the connection exists, Returns false if the Database index doesn't exist or if it's currently disconnected
        <ul>
          <li>intDatabaseIndex: Integer, Index of the Database</li>
        </ul>
      </li>
    </ul>
    <p>&nbsp;</p>
    <p><strong>gdatabase.CleanString(intDatabaseIndex, strString)</strong></p>
    <ul>
      <li>Returns the Cleaned/Escaped string
        <ul>
          <li><em>intDatabaseIndex</em>: Integer, Index of the Database</li>
          <li><em>strString</em>: String, String to be cleaned. i.e making &quot;HELLO's!&quot; -&gt; &quot;HELLO\'s!&quot;</li>
        </ul>
      </li>
    </ul>
    <p>&nbsp;</p>
    <h5 class="style3">gdatabase.threadedquery(strQuery, intDatabaseIndex, fnCallback, ...)</h5>
    <ul>
      <li>Creates a threaded query. Returns true if the thread was made, false if it failed.<br />
  NOTE: For threads there is a callback function that MUST be passed to this function. This function will at least need 1 incoming variable. This variable is the data that the thread recieved(Example Below). This value will be 0 if something happened(like an invalid query) and the data if the query was successful.
    <ul>
      <li><em>strQuery</em>: String, The query to be made</li>
      <li><em>intDatabaseIndex</em>: Integer, Index of the Database</li>
      <li><em>fnCallback</em>: Function, function that will be called and passed the query data once the thread is complete.</li>
      <li><em>...</em>: Anything, multiple arguments that will be passed to the callback function along with the Query data.</li>
      </ul>
      </li>
      <li>Example
        <div class="lua">function PrintData(query, strTitleText)<br />
if (query == 0) then<br />
print(&quot;QUERY FAILED!!!&quot;)<br />
return<br />
end<br />
--Print the Title<br />
print(strTitleText)<br />
PrintTable(query)<br />
end<br />
gdatabase.threadedquery(&quot;SELECT 1+1 FROM servers&quot;, 1, PrintData, &quot;SOME TITLE&quot;)</div>
        <!-- end #mainContent -->
      </li>
    </ul>
    <h5 class="style3">gdatabase.HookAdd(strHook, strUniqueName, fnHookFunction, intDatabaseIndex, ...)</h5>
    <ul>
      <li>Adds a hook to the database specified. This hook will run at the appropriate time.
        <ul>
          <li><em>strHook</em>: String, Name of the hook you want to hook to. ie. &quot;shutdown&quot;</li>
          <li><em>strUniqueName</em>: String, unique name of your hook to the function. This can be anything, this name will be used if you choose to remove it.</li>
          <li><em>fnHookFunction</em>: Function, the function that is to be ran when then the hook is called</li>
          <li><em>intDatabaseIndex</em>: Integer, Index of the Database</li>
          <li><em>...</em>: Anything, arguments that will be passed to the fnHookFunction when called.</li>
        </ul>
      </li>
    </ul>
    <h5 class="style3">gdatabase.HookRemove(strHook, strUniqueName, intDatabaseIndex)</h5>
    <ul>
      <li>Removes the specified hook
        <ul>
          <li><em>strHook</em>: String, Name of the hook. ie. &quot;shutdown&quot;</li>
          <li><em>strUniqueName</em>: String, unique name of your hook to the function. This is what your removing.</li>
          <li><em>intDatabaseIndex</em>: Integer, Index of the Database</li>
        </ul>
      </li>
    </ul>
    <h5 class="style3">gdatabase.AddTimer(strID, intInterval, intRep, intDatabaseIndex, fnCallback, ...)</h5>
    <ul>
      <li>Adds a timer that is attached to the database index passed. By doing this, GDatabase will control the stopping and starting of the timer as the connection goes up and down.
        <ul>
          <li><em>strID</em>: String, Name of the timer to create</li>
          <li><em>intInterval</em>: Integer, time between each timer call.</li>
          <li><em>intRep:</em> Integer, number of times to run the timer.</li>
          <li><em>intDatabaseIndex</em>: Integer, Index of the Database</li>
          <li><em>fnCallback</em>: Function, Function to call when the timer fires.</li>
          <li><em>...</em>: Anything, Arguments to pass to fnCallback</li>
        </ul>
      </li>
    </ul>
    <h5 class="style3">gdatabase.RemoveTimer(strID, intDatabaseIndex)</h5>
    <ul>
      <li>Removes a timer attached to the database index passed.
        <ul>
            <li><em>strID</em>: String, Name of the timer to create</li>
          <li><em>intDatabaseIndex</em>: Integer, Index of the Database</li>
        </ul>
      </li>
    </ul>
    <p>&nbsp;</p>
    <h4 class="style4">Hook Definitions</h4>
    <p class="style3">ALL IN LOWER CASE</p>
    <ul>
      <li><strong>shutdown</strong>: This hook is called when the server is shutting down. This will allow you to do any cleanup to your database before GDatabase unloads and you lose the connection.</li>
      <li><strong>query</strong>: This hook is called whenever a call to gdatabase.Query is made. This hook will only run if the query is valid.</li>
      <li><strong>keepalive</strong>: This hook is called whenever the Keep Alive is called by gdatabase.</li>
      <li><strong>reconnect</strong>: This hook is ran if the database reconnect is successful. A reconnect function is called every so often when the connection to the database is lost.</li>
      <li><strong>disconnect</strong>: This hook is ran when the database connection is internally killed due to 1: Keep Alive detects a connection problem 2: A console command calls for a database disconnect. This is also called when you specifically call for a kill with gdatabase.KillConnection.</li>
      <li><strong>connect</strong>: This hook is ran when the database connection is made. NOT THE INITIAL CONNECTION(Would be a little hard to add a hook if you don't have the Database index yet). The difference between this and the reconnect hook is that this one is called whenever GDatabase makes a connection. The Reconnect hook is only called when the reconnect timer fires and successfully reconnects. This one is much more useful.</li>
    </ul>
  </div>
  <div id="footer">
    <p>&nbsp;</p>
  <!-- end #footer --></div>
<!-- end #container --></div>
</body>
</html>
